Skip to content

docs: Candid interface guide#11

Merged
marc0olo merged 3 commits into
mainfrom
docs/guides-canister-calls-candid
Mar 16, 2026
Merged

docs: Candid interface guide#11
marc0olo merged 3 commits into
mainfrom
docs/guides-canister-calls-candid

Conversation

@marc0olo
Copy link
Copy Markdown
Member

@marc0olo marc0olo commented Mar 14, 2026

Summary

How-to guide for defining and using Candid interfaces. Covers:

  • The .did file format: service definitions, named types, init arguments
  • Type system with cross-language mapping table (Motoko, Rust, JavaScript), verified against .sources/candid (spec), .sources/motoko (IDL-Motoko.md), and .sources/cdk-rs
  • Generating .did files: automatic for Motoko, export_candid! + candid-extractor for Rust
  • Type mapping in practice: records and variants with code examples in all three languages
  • Interacting with interfaces: CLI (icp canister call), JavaScript (@icp-sdk/core + @icp-sdk/bindgen), inter-canister
  • Safe interface upgrade rules (subtyping, deprecation with reserved)
  • Candid tools: didc CLI command reference, Candid UI
  • JavaScript opt T tip (fromNullable/toNullable from @dfinity/utils)

Sync recommendation

Informed by dfinity/portaldocs/building-apps/interact-with-canisters/candid/ (3 files) and docs/building-apps/developer-tools/cdks/rust/generating-candid.mdx. Type mappings verified against .sources/candid, .sources/motoko, and .sources/cdk-rs.

Cover the Candid type system, .did file structure, type mapping between
Motoko/Rust/JavaScript, generating .did files for Rust canisters,
safe interface upgrades via subtyping rules, and Candid tooling (didc, Candid UI).
Copy link
Copy Markdown
Member Author

@marc0olo marc0olo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: Candid Interface

Must fix

None.

Suggestions

  1. icskills frontmatter is empty — The page covers Candid, which is cross-cutting. icskills: [multi-canister] could fit since Candid underpins inter-canister communication. Optional.

  2. JS SDK createActor import path — The example imports from "./declarations/my_canister", which is correct for icp-cli-generated projects. A brief note that these declarations are auto-generated during icp build would help readers understand where the import comes from. The content brief explicitly mentions @icp-sdk/core — the current example uses the declarations path instead. Both approaches are valid, but clarifying when to use which would be helpful.

  3. opt T JavaScript representation — The table shows [value] | [] for opt T in JavaScript. Technically correct at the IDL level, but in practice developers often use fromNullable()/toNullable() helpers from @dfinity/utils. A brief mention would be helpful but is not a blocker.

  4. Rust recipe version v3.2.0 — The version in the icp.yaml example is hardcoded. Templates in .sources/icp-cli-templates/ use v3.1.0. Verify that v3.2.0 actually exists, or use v3.1.0 (or a placeholder) instead.

  5. generate-did crate — Mentioned as an alternative to candid-extractor. Worth verifying that it is actively maintained on crates.io, since it is not an official DFINITY tool. If uncertain, flag with <!-- Needs human verification: is generate-did actively maintained? -->.

  6. Candid UI canister IDa4gq6-oaaaa-aaaab-qaa4q-cai is the well-known Candid UI canister. Looks correct but worth a quick sanity check.

Verified

  • All internal links resolve to existing files (canisters.md, candid-spec.md, onchain-calls.md, offchain-calls.md, binding-generation.md)
  • docs/concepts/canisters.md has a ### Query calls heading — anchor matches
  • Zero dfx references in the entire diff
  • CLI syntax icp canister call verified against .sources/icp-cli/docs/reference/cli.md
  • export_candid! macro usage verified against .sources/portal/ and .sources/examples/
  • Candid subtyping rules match portal source material (all 6 rules correct)
  • Type mapping table checked against Candid specification — accurate
  • Record/variant examples in Motoko and Rust are correct
  • icp.yaml Rust recipe format matches .sources/icp-cli-recipes/
  • candid-extractor workflow correct
  • didc CLI command table correct
  • Content brief fully covered (type system, service definitions, type mapping, Candid generation, JS actor creation, subtyping rules)
  • Source material was consulted (all 3 portal Candid files + Rust generating-candid)
  • No .mdx/JSX, plain .md, frontmatter complete
  • Page follows Diataxis how-to guide format: orient → explain → examples → next steps
  • Good scanability: clear headings, code examples, tables

Copy link
Copy Markdown
Member Author

@marc0olo marc0olo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: Candid Interface

Must fix

None.

Suggestions

  1. icskills frontmatter is empty — The page covers Candid, which is cross-cutting. icskills: [multi-canister] could fit since Candid underpins inter-canister communication. Optional.

  2. JS SDK createActor import path — The example imports from "./declarations/my_canister", which assumes pre-generated declarations. A brief note on how these declarations are produced (e.g., @icp-sdk/bindgen for JS/TS, or didc bind generically) would help readers understand where the import comes from. The content brief also mentions @icp-sdk/core — clarifying the relationship between the SDK and the declarations would be valuable.

  3. opt T JavaScript representation — The table shows [value] | [] for opt T in JavaScript. Technically correct at the IDL level, but in practice developers often use fromNullable()/toNullable() helpers from @dfinity/utils. A brief mention would be helpful but is not a blocker.

  4. Rust recipe version v3.2.0 — The version in the icp.yaml example is hardcoded. Templates in .sources/icp-cli-templates/ use v3.1.0. Verify that v3.2.0 actually exists, or use v3.1.0 (or a placeholder) instead.

  5. generate-did crate — Mentioned as an alternative to candid-extractor. Worth verifying that it is actively maintained on crates.io, since it is not an official DFINITY tool. If uncertain, flag with <!-- Needs human verification: is generate-did actively maintained? -->.

  6. Candid UI canister IDa4gq6-oaaaa-aaaab-qaa4q-cai is the well-known Candid UI canister. Looks correct but worth a quick sanity check.

Verified

  • All internal links resolve to existing files (canisters.md, candid-spec.md, onchain-calls.md, offchain-calls.md, binding-generation.md)
  • docs/concepts/canisters.md has a ### Query calls heading — anchor matches
  • Zero dfx references in the entire diff
  • CLI syntax icp canister call verified against .sources/icp-cli/docs/reference/cli.md
  • export_candid! macro usage verified against .sources/portal/ and .sources/examples/
  • Candid subtyping rules match portal source material (all 6 rules correct)
  • Type mapping table checked against Candid specification — accurate
  • Record/variant examples in Motoko and Rust are correct
  • icp.yaml Rust recipe format matches .sources/icp-cli-recipes/
  • candid-extractor workflow correct
  • didc CLI command table correct
  • Content brief fully covered (type system, service definitions, type mapping, Candid generation, JS actor creation, subtyping rules)
  • Source material was consulted (all 3 portal Candid files + Rust generating-candid)
  • No .mdx/JSX, plain .md, frontmatter complete
  • Page follows Diataxis how-to guide format: orient → explain → examples → next steps
  • Good scanability: clear headings, code examples, tables

Updated: corrected suggestion 2 regarding declaration generation (not handled by icp-cli build).

- Clarify JS SDK declaration generation: add @icp-sdk/bindgen and didc
  bind as explicit generation steps, mention @icp-sdk/core as runtime
- Add opt T JavaScript tip: fromNullable()/toNullable() from @dfinity/utils
- Drop generate-did crate (third-party wrapper around candid-extractor)
@marc0olo
Copy link
Copy Markdown
Member Author

Feedback addressed:

  • Clarified JS SDK declaration generation: added @icp-sdk/bindgen and didc bind as explicit steps, mentioned @icp-sdk/core as the runtime package
  • Added opt T JavaScript tip: fromNullable()/toNullable() from @dfinity/utils for idiomatic JS usage
  • Dropped generate-did crate — it's a third-party wrapper around candid-extractor that adds no value when the guide already shows the explicit steps
  • Verified Rust recipe v3.2.0 exists on icp-cli-recipes releases (no change needed)
  • Verified Candid UI canister ID a4gq6-oaaaa-aaaab-qaa4q-cai against portal docs (correct)
  • Left icskills: [] as-is — Candid is cross-cutting and doesn't map to a single icskill

- Fix bindgen invocation: --did-file/--out-dir (not --canister)
- Update sync comment to reference .sources/candid, .sources/motoko,
  and .sources/cdk-rs as verification sources
@marc0olo marc0olo merged commit 5adbf21 into main Mar 16, 2026
1 check passed
@marc0olo marc0olo deleted the docs/guides-canister-calls-candid branch March 16, 2026 16:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant